home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Think Class Libraries / Expander / Expander Classes / CFamily.cp < prev    next >
Encoding:
Text File  |  1994-11-30  |  4.8 KB  |  231 lines  |  [TEXT/KAHL]

  1. /***********************************************************************************
  2.     CFamily.h
  3.  
  4.     Copyright © 1994 B-Ray Software. All rights reserved.
  5.     Developed using Symantec C++ 7.0.2 and Symantec's TCL library.
  6.     Portions of this code courtesy Symantec, Inc.
  7.  
  8.     This code may be freely distributed as long as this notice remains. This code
  9.     may not be used in any commercial software without the consent of B-Ray Software.
  10.  
  11.     ---
  12.  
  13.     CFamily class methods. The CFamily class describes a relationship between
  14.     children and a parent. Although it is similar to the CCollaborator class, the
  15.     CFamily class is meant to be used as a base for Pane management, and I did not
  16.     want multiple CCollaborator-based classes floating around my derived CPane's.
  17.     Take a look at CExpanderPane to see what I mean.
  18.  
  19. ***********************************************************************************/
  20.  
  21. #include "CFamily.h"
  22.  
  23. typedef struct {
  24.     long        message;        // message identifier
  25.     void        *info;            // any information a child wants to convey
  26. } FamilyInfo;
  27.  
  28.  
  29. TCL_DEFINE_CLASS_M0( CFamily );
  30.  
  31.  
  32. /*
  33.  * Constructor
  34.  *
  35.  * Just initializes variables.
  36.  */
  37.  
  38. CFamily :: CFamily()
  39. {
  40.     itsParent = NULL;
  41.     itsChildren = NULL;
  42. }
  43.  
  44.  
  45. /*
  46.  * Destructor
  47.  *
  48.  * Just zaps out instance variables. Since classes derived from us will use multiple
  49.  * inheritance and a class from TCL, we don't want to zap anything on our end. Just
  50.  * hope that TCL cleans itself up properly.
  51.  */
  52.  
  53. CFamily :: ~CFamily()
  54. {
  55.     TCLForgetObject( itsChildren );
  56.     itsParent = NULL;
  57. }
  58.  
  59.  
  60. /*
  61.  * InsertChildAt method
  62.  *
  63.  * Adds a child to our list of children in the family. If a list of children does not
  64.  * exist, we create one.
  65.  */
  66.  
  67. void CFamily :: InsertChildAt( CFamily *aChild, long index )
  68. {
  69.     if ( itsChildren == NULL ) {
  70.         itsChildren = TCL_NEW( CFamilyList, () );
  71.     }
  72.  
  73.     aChild->SetParent( this );
  74.     itsChildren->InsertAt( aChild, index );
  75. }
  76.  
  77.  
  78. /*
  79.  * RemoveChildAt method
  80.  *
  81.  * Removes the child at the given index.
  82.  */
  83.  
  84. void CFamily :: RemoveChildAt( long index )
  85. {
  86.     if ( itsChildren )
  87.         itsChildren->DeleteItem( index );
  88. }
  89.  
  90.  
  91. /*
  92.  * ResolveToLeaf method
  93.  *
  94.  * Walks the family tree until it hits a leaf node. The beginOrEnd parameter indicates
  95.  * whether we always keap to the left (begin) or right (end) of our list of children nodes.
  96.  * Specifying anything else is really meaningless.
  97.  */
  98.  
  99. CFamily *CFamily :: ResolveToLeaf( Boolean beginOrEnd )
  100. {
  101.     CFamily    *aChild = NULL;
  102.  
  103.     if ( itsChildren ) {
  104.         aChild = beginOrEnd ? LastChild() : FirstChild();    // get child of interest
  105.         if ( aChild ) {
  106.             aChild = aChild->ResolveToLeaf( beginOrEnd );    // and resolve it
  107.         }
  108.     }
  109.  
  110.     if ( aChild == NULL ) {
  111.         aChild = this;            // return ourselves if no children are available
  112.     }
  113.  
  114.     return aChild;
  115. }
  116.  
  117.  
  118. /*
  119.  * TellChild method
  120.  *
  121.  * Given a message indicator and some information, this routine will tell all of the children
  122.  * the message and info. Works much like the BroadcastChange() method for CCollaborator.
  123.  */
  124.  
  125.     static void TellEachChild( CFamily *aChild, long param )
  126.     {
  127.         FamilyInfo    *info = (FamilyInfo *)param;
  128.         aChild->ParentMessage( info->message, info->info );
  129.     }
  130.  
  131. void CFamily :: TellChildren( long message, void *param )
  132. {
  133.     FamilyInfo    info;
  134.  
  135.     if ( itsChildren ) {
  136.         info.message = message;
  137.         info.info = param;
  138.         itsChildren->DoForEach1( TellEachChild, (long )&info );
  139.     }
  140. }
  141.  
  142.  
  143. /*
  144.  * TellParent method
  145.  *
  146.  * Simply tells the parent what the message was.
  147.  */
  148.  
  149. void CFamily :: TellParent( long message, void *param )
  150. {
  151.     if ( itsParent ) {
  152.         itsParent->ChildMessage( this, message, param );
  153.     }
  154. }
  155.  
  156.  
  157. /*
  158.  * ChildMessage method
  159.  *
  160.  * Received a message from a child. Just pass it on to our parent. We don't respond to
  161.  * specific messages.
  162.  */
  163.  
  164. void CFamily :: ChildMessage( CFamily *aChild, long message, void *param )
  165. {
  166.     TellParent( message, param );
  167. }
  168.  
  169.  
  170. /*
  171.  * ParentMessage method
  172.  *
  173.  * Received a message from our parent. Just pass it on to our children. We don't respond
  174.  * to specific messages.
  175.  */
  176.  
  177. void CFamily :: ParentMessage( long message, void *param )
  178. {
  179.     TellChildren( message, param );
  180. }
  181.  
  182.  
  183. /*
  184.  * PutTo method
  185.  *
  186.  * Writes to the stream all of the info we need to save.
  187.  */
  188.  
  189. void CFamily :: PutTo( CStream &stream )
  190. {
  191.     long    loop, numChildren = GetNumberChildren();
  192.     CFamily    *aChild;
  193.  
  194.     stream << numChildren;
  195.  
  196.     for ( loop = 1; loop <= numChildren; ++loop ) {
  197.         aChild = itsChildren->NthItem( loop );
  198.         PutObject( stream, aChild );
  199.     }
  200.  
  201.     aChild = itsParent;
  202.     PutObject( stream, aChild );
  203. }
  204.  
  205.  
  206. /*
  207.  * GetFrom method
  208.  *
  209.  * Reads from the stream all of the info that we saved.
  210.  */
  211.  
  212. void CFamily :: GetFrom( CStream &stream )
  213. {
  214.     long    loop, numChildren;
  215.     CFamily    *aChild;
  216.     CPane    *aPane;
  217.  
  218.     stream >> numChildren;
  219.     if ( numChildren > 0 ) {
  220.         itsChildren = TCL_NEW( CFamilyList, () );
  221.         for ( loop = 1; loop <= numChildren; ++loop ) {
  222.             GetObject( stream, aChild );
  223.             TCL_ASSERT( aChild != NULL );
  224.             itsChildren->InsertAt( aChild, loop );
  225.         }
  226.     }
  227.  
  228.     GetObject( stream, aChild );
  229.     itsParent = aChild;
  230. }
  231.